package com.example.object.game;

import android.content.Context;
import android.util.Log;

import com.example.bounce.R;
import com.example.globject.GLSquare;
import com.example.object.GameShape;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;

/**
 * Created by Lucas on 03/07/13.
 */
public class Ball extends GameShape{

    /**
     * The glSquare containing the texture and handle the drawing part of the object
     */
    private GLSquare _glSquare;
    /**
     * The bodyDef from JBox2D of the ball
     */
    private BodyDef _bodyDef;
    /**
     * The Body from JBox2D of the bal
     */
    private Body _body;
    /**
     * the point x,y of the center of the ball
     */
    private float _xCenter, _yCenter;
    /**
     * The size of the ball
     */
    private float size;
    /**
     * The debug TAG
     */
    private final String TAG = "Ball";

    /**
     * Constructor of the Ball Object
     * @param context the context of the aplication
     * @param xCenter the coordinate x of the origin point
     * @param yCenter the coordinate y of the origin point
     * @param midHeight the height of the ball
     * @param midWidth the width of the ball
     */
    public Ball(Context context, float xCenter, float yCenter, float midHeight, float midWidth){
        Log.i(TAG, "BallShape constructor");
        // doesn't need to be initialized
        _userData = 0;
        _handlerInitiate = true;

        _xCenter = xCenter;
        _yCenter = yCenter;
        size = midHeight;
        _glSquare = new GLSquare(context, xCenter, yCenter, midHeight, midWidth, R.raw.tennisball);

        // create definition
        _bodyDef = new BodyDef();
        _bodyDef.position.set(new Vec2(xCenter, yCenter));
        _bodyDef.type = BodyType.DYNAMIC;
        _bodyDef.bullet = true;
    }

    /**
     * Add the JBox2D object into the JBox2D world
     * @param world the JBox2D world
     */
    public void addToWorld(World world){
        // step 2 : create the body;
        _body = world.createBody(_bodyDef);
        // step 3 : create the fixture;
        // need to reverse the width and height for some reason
        CircleShape shape = new CircleShape();
        shape.m_p.set(new Vec2(_xCenter, _yCenter));
        shape.m_radius = size;
        FixtureDef fd = new FixtureDef();
        fd.shape = shape;
        fd.density = 400f;
        //fd.friction = 0f;
        fd.restitution = 0.5511f;
        _body.createFixture(fd);
    }

    /**
     * Set the gl handler to draw the object
     * @param positionHandle
     * @param textureHandle
     * @param MVPMatrixHandle
     * @param vMatrix
     * @param projMatrix
     */
    public void setGLHandler(int positionHandle, int textureHandle, int MVPMatrixHandle,
                             float vMatrix[], float projMatrix[]){
        _glSquare.setGLHandler(positionHandle, textureHandle, MVPMatrixHandle, vMatrix, projMatrix, null);
        _handlerInitiate = true;
    }

    /**
     * @return true
     */
    @Override
    public boolean isMovable() {
        return true;
    }

    /**
     * @return true
     */
    @Override
    public boolean isRotatable() {
        return true;
    }

    /**
     * Move the ball to the position describe by the parameters
     * @param toX the coordinate x of the origin point
     * @param toY the coordinate y of the origin point
     */
    @Override
    public void moveTo(float toX, float toY) {
        _glSquare.moveTo(toX, toY);
        _body.getWorldCenter().set(new Vec2(toX, toY));
    }

    /**
     * @return true
     */
    @Override
    public boolean isTouchable() {
        return true;
    }

    @Override
    public Body getBody() {
        return _body;
    }

    /**
     * Calculation of the next position of the ball.
     */
    @Override
    public void calculateNextCoordinate() {
        if (_body.isActive()){
            Vec2 position =  _body.getWorldCenter();
            moveTo(position.x, position.y);
        }
    }

    /**
     * Return if the ball is touch by an input event
     * @param touch the input point of touch
     * @return true is the ball is touched
     */
    public boolean isTouched(Vec2 touch){
        //TODO change method isTouched
        Vec2 currentPosition = _body.getWorldCenter();
        if (touch.x > currentPosition.x-size && touch.x < currentPosition.x+size &&
            touch.y > currentPosition.y-size && touch.y < currentPosition.y+size){
            Log.d(TAG, "Ball is touched");
            return true;
        }
        return false;
    }

    /**
     * draw the globject of the ball
     */
    @Override
    public void draw(){
        _glSquare.draw();
    }

    public String toString(){
        return "\n glSquare: " + _glSquare.toString();
    }

    public GLSquare getGLSquare(){
        return _glSquare;
    }

    public void applyForce(Vec2 touch) {
        _body.getWorldCenter().set(touch);
    }
}
